package cn.com.headfree.base.initData;

import cn.com.headfree.base.entity.TOuterDept;
import cn.com.headfree.base.entity.TOuterDeptUser;
import cn.com.headfree.base.entity.TOuterUser;
import cn.com.headfree.deptuser.service.TOrgDeptService;
import cn.com.headfree.deptuser.service.TOuterDeptService;
import cn.com.headfree.deptuser.service.TOuterUserService;
import cn.com.headfree.entity.TOrgDept;
import cn.com.headfree.mouldshow.service.TEmpBaseInfoService;
import cn.com.headfree.util.SysDictionaryUtil;
import cn.com.headfree.vo.DeptUserNumVo;
import cn.com.headfree.vo.UserInfoVo;
import cn.com.headfree.vo.UserVo;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.springframework.web.context.WebApplicationContext;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.Map.Entry;

public class InitData {
	private static InitData instance;
	private static final org.apache.logging.log4j.Logger LOG = LogManager.getLogger(InitData.class);
	private Map<String,Object> data = new HashMap<String,Object>();
	public static final String ROOT = "root";
	
	private InitData() {
	}

	public static InitData getInstance() {
		synchronized (InitData.class) {
			if (instance == null) {
				instance = new InitData();
			}
			return instance;
		}
	}
	
	public void initData(WebApplicationContext app) {
		LOG.info("************初始化机构及人员开始******************");
		try {
			initDeptData(app);
			LOG.info("************初始化机构及人员完成******************");
		} catch (Exception e) {
			LOG.info("************初始化机构及人员失败******************", e);
		}
		LOG.info("************初始化数据字典开始******************");
		try {
			SysDictionaryUtil.initSysDictionaryInfo(app);
			LOG.info("************初始化数据字典完成******************");
		} catch (Exception e) {
			LOG.info("************初始化数据字典失败******************", e);
		}
//		LOG.info("************初始化人员类型开始******************");
//		try {
//			initUserType(app);
//			LOG.info("************初始化人员类型完成******************");
//		} catch (Exception e) {
//			LOG.info("************初始化人员类型失败******************", e);
//		}
//		LOG.info("************初始化人员信息开始******************");
//		try {
//			initUserInfoData(app);
//			LOG.info("************初始化人员信息完成******************");
//		} catch (Exception e) {
//			LOG.info("************初始化人员信息失败******************", e);
//		}
	}

	public void initUserInfoData(WebApplicationContext app) {
		TOuterUserService userService = (TOuterUserService) app.getBean("tOuterUserService");
		TOuterDeptService deptService = (TOuterDeptService) app.getBean("tOuterDeptService");
		List<TOuterUser> userList = userService.findALL();
		List<TOuterDept> deptList = deptService.findAll();
		List<TOuterDeptUser> deptUserList = userService.findDeptAndUserAll();
		Map<String,UserInfoVo> userVoMap = new HashMap<String,UserInfoVo>(userList.size());
		Map<String,TOuterDept> deptMap = new HashMap<String,TOuterDept>(deptList.size());
		// 人员ID为健，值为对象
		UserInfoVo vo = null;
		Object obj = data.get("USER_TYPE");
		Properties prop = null;
		if (obj != null) {
			prop = (Properties)obj;
		} else {
			LOG.error("*****************************************初始化人员类型失败！***************************************************************");
			return;
		}
		for (TOuterUser user : userList) {
			vo = this.getUserInfoVo(user);
			if (!StringUtils.isBlank(vo.getUserTypeValue())) {
				vo.setUserTypeName(prop.getProperty(vo.getUserTypeValue()));
			}
			userVoMap.put(user.getId(), vo);
		}
		// 部门ID为健，值为对象
		for (TOuterDept dept : deptList) {
			deptMap.put(dept.getId(), dept);
		}
		// 健为用户ID，值为用户所在的部门的集合
		for (TOuterDeptUser du : deptUserList) {
			if (userVoMap.get(du.getUserId()) == null) {
				continue;
			}
			if (userVoMap.get(du.getUserId()).getDepts() == null) {
				userVoMap.get(du.getUserId()).setDepts(new ArrayList<TOuterDept>());
			}
			userVoMap.get(du.getUserId()).getDepts().add(deptMap.get(du.getDeptId()));
		}
		data.put("USER_INFOS", userVoMap);
	}
	
	private UserInfoVo getUserInfoVo(TOuterUser user) {
		UserInfoVo vo = new UserInfoVo();
		vo.setId(user.getId());
		vo.setActive(user.getActive());
		vo.setAvatar(user.getAvatar());
		vo.setEmail(user.getEmail());
		vo.setIsAdmin(user.getIsAdmin());
		vo.setIsBoss(user.getIsBoss());
		vo.setIsHide(user.getIsHide());
		vo.setIsLeaderInDepts(user.getIsLeaderInDepts());
		vo.setIsSenior(user.getIsSenior());
		vo.setJobnumber(user.getJobnumber());
		vo.setMobile(user.getMobile());
		vo.setName(user.getName());
		vo.setOpenId(user.getOpenId());
		vo.setOrderInDepts(user.getOrderInDepts());
		vo.setPosition(user.getPosition());
		vo.setRemark(user.getRemark());
		vo.setStateCode(user.getStateCode());
		vo.setTel(user.getTel());
		vo.setUnionid(user.getUnionid());
		vo.setUserTypeValue(user.getUserType());
		vo.setWorkPlace(user.getWorkPlace());
		vo.setErpNo(user.getErpNo());
		return vo;
	}
	
	/**
	 * 
	 * @description 从properties文件里面讲userType进行转化
	 * @author 徐亮
	 * @date 2019年5月5日 上午9:30:49
	 * @param app
	 * @return
	 * void
	 */
//	public void initUserType(WebApplicationContext app) {
//		  LOG.info("************初始化人员类型******************");
//		  try {
//			  Properties p = new Properties();
//			  InputStream is = InitData.class.getClassLoader().getResourceAsStream("usertype.properties");
//				try {
//					p.load(is);
//					data.put("USER_TYPE", p);
//				} catch (IOException e) {
//					e.printStackTrace();
//				}
//		  } catch (Exception e) {
//			  LOG.info("************初始化人员类型失败******************", e);
//		  }
//	  }

	private void initDeptData(WebApplicationContext app) {
//		TOuterUserService userService = (TOuterUserService) app.getBean("tOuterUserService");
//		TOuterDeptService deptService = (TOuterDeptService) app.getBean("tOuterDeptService");

		TOrgDeptService tOrgDeptService = (TOrgDeptService) app.getBean("tOrgDeptService");
		TEmpBaseInfoService empBaseInfoService = (TEmpBaseInfoService) app.getBean("tEmpBaseInfoService");
		// 获取所有的部门信息
//		List<TOuterDept> allDepts = deptService.findAll();
		List<TOrgDept> allDepts = tOrgDeptService.findAllByPId();

		Map<String,DeptUserNumVo> deptUserNumMap = new HashMap<String,DeptUserNumVo>();
		// 获取所有的部门和人员的关联表信息
//		List<UserVo> allDeptUsers = userService.findDeptUserAll();
		List<UserVo> allDeptUsers = empBaseInfoService.findAllByBaseOrgId("10342674");
		// 根据部门和部门与人员的关联表，获取每个部门下的人员数量(去重)
		Map<String,Set<UserVo>> deptUserMap = new HashMap<String,Set<UserVo>>();
		// 根据部门和部门与人员的关联表，获取每个部门下的人员数量(不去重)
		Map<String,List<UserVo>> deptUserList = new HashMap<String,List<UserVo>>();
		this.getDeptUserNum(allDepts, allDeptUsers, deptUserNumMap);
		// 根据部门机构进行部门按照等级进行数据机构封装
		Map<String,Object> deptClassMap = new HashMap<String,Object>();
		this.getDeptClass(allDepts, deptClassMap, deptUserNumMap,allDeptUsers);
		this.totalDeptUser(deptClassMap, deptUserMap, "10342674",null);
		this.totalDeptUserList(deptClassMap, deptUserList, "10342674",null);
		Map<String,Object> deptData = new HashMap<String,Object>();
		deptData.put("DEPT_CLASS_USER_NUM", deptClassMap);
		deptData.put("ALL_DEPT", allDepts);
		deptData.put("DEPT_USERS_SET", deptUserMap);
		deptData.put("DEPT_USERS_LIST", deptUserList);
		//把所有部门信息写入内存中
		data.put("DEPT_DATA",deptData);
	}
	
	private void totalDeptUser(Map<String,Object> deptClassMap,Map<String,Set<UserVo>> deptUserMap,String deptId,String parentDeptId) {
		Object obj = deptClassMap.get(deptId);
		Map<String,Object> deptUser = (Map<String,Object>)obj;
		List<DeptUserNumVo> deptUserList = (List<DeptUserNumVo>)deptUser.get("depts");
		List<UserVo> deptUsers = (List<UserVo>)deptUser.get("users");
		List<DeptUserNumVo> temp = deptUserList;
		if (temp.size() > 0) {
			for (DeptUserNumVo numVo : temp) {
				obj = deptClassMap.get(numVo.getDeptId());
				deptUser = (Map<String,Object>)obj;
				temp = (List<DeptUserNumVo>)deptUser.get("depts");
				this.totalDeptUser(deptClassMap, deptUserMap, numVo.getDeptId(),String.valueOf(numVo.getParentId()));
			}
		}
		this.totalUserSet(deptClassMap, deptUserMap, deptId,parentDeptId);
	}
	
	private void totalDeptUserList(Map<String,Object> deptClassMap,Map<String,List<UserVo>> list,String deptId,String parentDeptId) {
		Object obj = deptClassMap.get(deptId);
		Map<String,Object> deptUser = (Map<String,Object>)obj;
		List<DeptUserNumVo> deptUserList = (List<DeptUserNumVo>)deptUser.get("depts");
		List<UserVo> deptUsers = (List<UserVo>)deptUser.get("users");
		List<DeptUserNumVo> temp = deptUserList;
		if (temp.size() > 0) {
			for (DeptUserNumVo numVo : temp) {
				obj = deptClassMap.get(numVo.getDeptId());
				deptUser = (Map<String,Object>)obj;
				temp = (List<DeptUserNumVo>)deptUser.get("depts");
				this.totalDeptUserList(deptClassMap, list, numVo.getDeptId(),String.valueOf(numVo.getParentId()));
			}
		}
		this.totalUserList(deptClassMap, list, deptId,parentDeptId);
	}
	
	private void totalUserList(Map<String,Object> deptClassMap,Map<String,List<UserVo>> userMap,String deptId,String parentDeptId) {
		Object obj = deptClassMap.get(deptId);
		Map<String,Object> deptUser = (Map<String,Object>)obj;
		List<UserVo> deptUsers = (List<UserVo>)deptUser.get("users");
		List<UserVo> userSet = userMap.get(deptId);
		if (userSet == null) {
			userSet = new ArrayList<UserVo>();
			userMap.put(deptId, userSet);
		}
		userMap.get(deptId).addAll(deptUsers);
		if (parentDeptId != null) {
			userSet = userMap.get(parentDeptId);
			if (userSet == null) {
				userSet = new ArrayList<UserVo>();
				userMap.put(parentDeptId, userSet);
			}
			userMap.get(parentDeptId).addAll(userMap.get(deptId));
		}
	}
	
	private void totalUserSet(Map<String,Object> deptClassMap,Map<String,Set<UserVo>> deptUserMap,String deptId,String parentDeptId) {
		Object obj = deptClassMap.get(deptId);
		Map<String,Object> deptUser = (Map<String,Object>)obj;
		List<UserVo> deptUsers = (List<UserVo>)deptUser.get("users");
		Set<UserVo> userSet = deptUserMap.get(deptId);
		if (userSet == null) {
			userSet = new HashSet<UserVo>();
			deptUserMap.put(deptId, userSet);
		}
		deptUserMap.get(deptId).addAll(deptUsers);
		if (parentDeptId != null) {
			userSet = deptUserMap.get(parentDeptId);
			if (userSet == null) {
				userSet = new HashSet<UserVo>();
				deptUserMap.put(parentDeptId, userSet);
			}
			deptUserMap.get(parentDeptId).addAll(deptUserMap.get(deptId));
		}
	}
	
	
	
	/**
	 * @description 
	 * @author 冯亚
	 * @date 2019年4月28日 上午10:14:16
	 * @param deptClassMap
	 * @param deptUserNumMap
	 * @return
	 * void
	 */
	private void getDeptClass(List<TOrgDept> allDepts,Map<String,Object> deptClassMap,Map<String,DeptUserNumVo> deptUserNumMap,List<UserVo> allDeptUsers) {
		List<DeptUserNumVo> deptUserList = null;
		Map<String,Object> deptMap = null;
		List<UserVo> deptUsers = null;
		for (TOrgDept dept : allDepts) {
			deptMap = new HashMap<String,Object>();
			deptUserList = new ArrayList<DeptUserNumVo>();
			for (TOrgDept dp : allDepts) {
				if (dept.getId().equals(String.valueOf(dp.getpId()))) {
					deptUserList.add(deptUserNumMap.get(dp.getId()));
				}
			}
			Collections.sort(deptUserList);
			deptMap.put("depts", deptUserList);
			// 对该部门下的人员进行组合
			deptUsers = new ArrayList<UserVo>();
			for (UserVo vo : allDeptUsers) {
				if (vo.getDeptId().equals(dept.getId())) {
					deptUsers.add(vo);
				}
			}
			deptMap.put("users", deptUsers);
			deptClassMap.put(dept.getId(), deptMap);
		}
	}
	
	/**
	 * @description 根据部门和部门与人员的关联表，获取每个部门下的人员数量
	 * @author 冯亚
	 * @date 2019年4月28日 上午8:49:05
	 * @param allDepts
	 * @param allDeptUsers
	 * @param deptUserNumMap
	 * @return
	 * void
	 */
	private void getDeptUserNum(List<TOrgDept> allDepts,List<UserVo> allDeptUsers,Map<String,DeptUserNumVo> deptUserNumMap) {
		DeptUserNumVo deptUserNum = null;
		Map<String,TOrgDept> deptMap = new HashMap<String,TOrgDept>(allDepts.size());
		for (TOrgDept dept : allDepts) {
			deptUserNum = new DeptUserNumVo();
			deptUserNum.setDeptId(dept.getId());
			deptUserNum.setName(dept.getName());
			deptUserNum.setParentId(dept.getpId());
			for (UserVo deptUser : allDeptUsers) {
				if (deptUser.getDeptId().equals(dept.getId())) {
					deptUser.setUserType("10000");
					deptUserNum.setFormalNum(deptUserNum.getFormalNum() + 1);
				}
			}
			deptUserNumMap.put(dept.getId(), deptUserNum);
			deptMap.put(dept.getId(), dept);
		}
		Set<Entry<String,DeptUserNumVo>> DeptUserNumSet = deptUserNumMap.entrySet();
		DeptUserNumVo vo = null;
		DeptUserNumVo temp = new DeptUserNumVo();
		TOrgDept dept = null;
		//遍历所有的部门人员数量，把子部门人员数向父部门进行汇总
		for (Entry<String,DeptUserNumVo> entry : DeptUserNumSet) {
			vo = entry.getValue();
			dept = deptMap.get(entry.getKey());
			if (dept != null && !dept.getId().equals("10342674") ) {
				temp.setFormalNum(temp.getFormalNum() + vo.getFormalNum());
			}
		}
	}

	public Map<String, Object> getData() {
		return data;
	}

}
